﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace LaserTag.Common.Controls
{
    public class TargetReticle : Control
    {
        private FrameworkElement m_reticle;
        private FrameworkElement m_reticleTargetArea;

        static TargetReticle()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(TargetReticle),
                                                     new FrameworkPropertyMetadata(typeof(TargetReticle)));
        }

        #region ReticleCenter

        public static readonly DependencyProperty ReticleCenterProperty =
            DependencyProperty.Register("ReticleCenter", typeof(Point), typeof(TargetReticle),
                                        new FrameworkPropertyMetadata(new Point(),
                                                                      new PropertyChangedCallback(OnReticleCenterChanged)));

        public Point ReticleCenter
        {
            get { return (Point)GetValue(ReticleCenterProperty); }
            set { SetValue(ReticleCenterProperty, value); }
        }

        private static void OnReticleCenterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((TargetReticle)d).OnReticleCenterChanged(e);
        }

        protected virtual void OnReticleCenterChanged(DependencyPropertyChangedEventArgs e)
        {
            SetReticlePosition();
        }

        #endregion

        #region TargetAreaSize

        public static readonly DependencyProperty TargetAreaSizeProperty =
            DependencyProperty.Register("TargetAreaSize", typeof(Size), typeof(TargetReticle),
                                        new FrameworkPropertyMetadata(new Size(),
                                                                      new PropertyChangedCallback(OnTargetAreaSizeChanged)));


        public Size TargetAreaSize
        {
            get { return (Size)GetValue(TargetAreaSizeProperty); }
            set { SetValue(TargetAreaSizeProperty, value); }
        }

        private static void OnTargetAreaSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((TargetReticle)d).OnTargetAreaSizeChanged(e);
        }

        protected virtual void OnTargetAreaSizeChanged(DependencyPropertyChangedEventArgs e)
        {
            SetReticlePosition();
        }

        #endregion

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            m_reticle = GetTemplateChild("PART_Reticle") as FrameworkElement;
            m_reticleTargetArea = GetTemplateChild("PART_ReticleTargetArea") as FrameworkElement;
        }

        private void SetReticlePosition()
        {
            if (m_reticle == null || m_reticleTargetArea == null)
                return;

            if(m_reticle.RenderTransform == null)
            {
                m_reticle.RenderTransform = new TranslateTransform();
            }

            var translation = m_reticle.RenderTransform as TranslateTransform;

            if(translation == null && m_reticle.RenderTransform is TransformGroup)
            {
                var transformGroup = m_reticle.RenderTransform as TransformGroup;

                foreach(var transform in transformGroup.Children)
                {
                    var translateTransform = transform as TranslateTransform;
                    if(translateTransform != null)
                    {
                        translation = translateTransform;
                        break;
                    }
                }
            }
            
            if(translation == null)
            {
                translation = new TranslateTransform();
                m_reticle.RenderTransform = translation;
            }

            double percentLeft = ReticleCenter.X / TargetAreaSize.Width;
            double percentTop = ReticleCenter.Y / TargetAreaSize.Height;

            translation.X = (m_reticleTargetArea.ActualWidth * percentLeft) - m_reticle.ActualWidth /2;
            translation.Y = (m_reticleTargetArea.ActualHeight * percentTop) - m_reticle.ActualHeight /2;
        }
    }
}